<!DOCTYPE html>
<html lang="en">

<!-- Head tag -->
<head><meta name="generator" content="Hexo 3.8.0">

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!--Description-->

    

    
        <meta name="description" content="一、生成代码框架ONVIF编译和简单代码，可以看看这个系列：https://blog.csdn.net/benkaoya/article/details/72424335 感谢博主的无私奉献，当然，如果源码下载积分可以低一点就更好了（没积分下载不了）。看这篇文章前可以先看看，方便理解。
练手，了解一">
    

    <!--Author-->
    
        <meta name="author" content="Cyrus">
    

    <!--Open Graph Title-->
    
        <meta property="og:title" content="ONVIF 客户端生成代码框架和简单封装">
    

    <!--Open Graph Description-->
    
        <meta property="og:description" content="一、生成代码框架ONVIF编译和简单代码，可以看看这个系列：https://blog.csdn.net/benkaoya/article/details/72424335 感谢博主的无私奉献，当然，如果源码下载积分可以低一点就更好了（没积分下载不了）。看这篇文章前可以先看看，方便理解。
练手，了解一">
    

    <!--Open Graph Site Name-->
        <meta property="og:site_name" content="Cyrus的技术空间">

    <!--Type page-->
    
        <meta property="og:type" content="article">
    

    <!--Page Cover-->
    
    
        <meta property="og:image" content="http://cyrus_huang.gitee.io/bloghttp://www.codeblocq.com/assets/projects/hexo-theme-clean-blog/img/home-bg.jpg">
    

        <meta name="twitter:card" content="summary_large_image">

    

    
        <meta name="twitter:image" content="http://cyrus_huang.gitee.io/bloghttp://www.codeblocq.com/assets/projects/hexo-theme-clean-blog/img/home-bg.jpg">
    

    <!-- Title -->
    
    <title>ONVIF 客户端生成代码框架和简单封装 - Cyrus的技术空间</title>

    <!-- Bootstrap Core CSS -->
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">

    <!-- Custom CSS -->
    <link rel="stylesheet" href="/blog/css/style.css">

    <!-- Custom Fonts -->
    <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" type="text/css">
    <link href="//fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic" rel="stylesheet" type="text/css">
    <link href="//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css">

    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="//oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

    <!-- Gallery -->
    <link href="//cdnjs.cloudflare.com/ajax/libs/featherlight/1.3.5/featherlight.min.css" type="text/css" rel="stylesheet">

    <!-- Google Analytics -->
    


    <!-- favicon -->
    

</head>


<body>

    <!-- Menu -->
    <!-- Navigation -->
<nav class="navbar navbar-default navbar-custom navbar-fixed-top">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header page-scroll">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/blog/">Cyrus的技术空间</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav navbar-right">
                
                    <li>
                        <a href="/blog/">
                            
                                Home
                            
                        </a>
                    </li>
                
                    <li>
                        <a href="/blog/archives">
                            
                                Archives
                            
                        </a>
                    </li>
                
                    <li>
                        <a href="/blog/tags">
                            
                                Tags
                            
                        </a>
                    </li>
                
                    <li>
                        <a href="/blog/categories">
                            
                                Categories
                            
                        </a>
                    </li>
                
                    <li>
                        <a href="https://github.com/klugjo/hexo-theme-clean-blog">
                            
                                <i class="fa fa-github fa-stack-2x"></i>
                            
                        </a>
                    </li>
                
            </ul>
        </div>
        <!-- /.navbar-collapse -->
    </div>
    <!-- /.container -->
</nav>

    <!-- Main Content -->
    <!-- Page Header -->
<!-- Set your background image for this header in your post front-matter: cover -->

<header class="intro-header" style="background-image: url('http://www.codeblocq.com/assets/projects/hexo-theme-clean-blog/img/home-bg.jpg')">
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <div class="post-heading">
                    <h1>ONVIF 客户端生成代码框架和简单封装</h1>
                    
                    <span class="meta">
                        <!-- Date and Author -->
                        
                            Posted by Cyrus on
                        
                        
                            2020-01-15
                        
                    </span>
                </div>
            </div>
        </div>
    </div>
</header>

<!-- Post Content -->
<article>
    <div class="container">
        <div class="row">

            <!-- Tags and categories -->
           

            <!-- Gallery -->
            

            <!-- Post Main Content -->
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <h3 id="一、生成代码框架"><a href="#一、生成代码框架" class="headerlink" title="一、生成代码框架"></a>一、生成代码框架</h3><p>ONVIF编译和简单代码，可以看看这个系列：<a href="https://blog.csdn.net/benkaoya/article/details/72424335" target="_blank" rel="noopener">https://blog.csdn.net/benkaoya/article/details/72424335</a> 感谢博主的无私奉献，当然，如果源码下载积分可以低一点就更好了（没积分下载不了）。看这篇文章前可以先看看，方便理解。</p>
<p>练手，了解一下ONVIF,主要操作有，查找设备、获取设备信息、设备能力、设备profile和简单的ptz控制。因为上面的系列教程没有涉及ptz，所以在wsdl2h 生成头文件时，加上 <a href="http://www.onvif.org/onvif/ver20/ptz/wsdl/ptz.wsdl" target="_blank" rel="noopener">http://www.onvif.org/onvif/ver20/ptz/wsdl/ptz.wsdl</a> 以获取ptz相关功能。</p>
<h3 id="二、简单封装"><a href="#二、简单封装" class="headerlink" title="二、简单封装"></a>二、简单封装</h3><h4 id="1、创建一个device结构体，用来保存设备数据及相关方法："><a href="#1、创建一个device结构体，用来保存设备数据及相关方法：" class="headerlink" title="1、创建一个device结构体，用来保存设备数据及相关方法："></a>1、创建一个device结构体，用来保存设备数据及相关方法：</h4><p>OnvifDevice.h<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line">#ifndef OnvifDevice_h</span><br><span class="line">#define OnvifDevice_h</span><br><span class="line"></span><br><span class="line">#include &lt;stdio.h&gt;</span><br><span class="line">#include &lt;stdlib.h&gt;</span><br><span class="line">#include &lt;assert.h&gt;</span><br><span class="line">#include &quot;soapH.h&quot;</span><br><span class="line">#include &quot;wsaapi.h&quot;</span><br><span class="line">#include &quot;wsseapi.h&quot;</span><br><span class="line"></span><br><span class="line">#ifdef __cplusplus</span><br><span class="line">extern &quot;C&quot;&#123;</span><br><span class="line">#endif</span><br><span class="line"></span><br><span class="line">typedef struct oc_device &#123;</span><br><span class="line">    char *xAddr;		// 搜索得到的地址</span><br><span class="line">    char *userName;		// 用户名</span><br><span class="line">    char *password;		// 地址</span><br><span class="line">    struct _tds__GetDeviceInformationResponse  devinfo;	// 设备信息</span><br><span class="line">    struct tt__Capabilities  capabilities;		// 设备能力</span><br><span class="line">    struct _trt__GetProfilesResponse profiles;	// profiles</span><br><span class="line">&#125;oc_device_t;</span><br><span class="line"></span><br><span class="line">// 创建设备</span><br><span class="line">oc_device_t *createDevice(const char *xAddr, const char *userName, const char *password);</span><br><span class="line">// 删除设备</span><br><span class="line">void destroyDevice(oc_device_t *device);</span><br><span class="line"></span><br><span class="line">// 保存设备信息</span><br><span class="line">void setInfo(oc_device_t *device, struct _tds__GetDeviceInformationResponse  *info);</span><br><span class="line">// 删除设备信息</span><br><span class="line">void removeInfo(oc_device_t *device);</span><br><span class="line"></span><br><span class="line">// 保存设备能力</span><br><span class="line">void setCapabilities(oc_device_t *device, struct tt__Capabilities  *capa);</span><br><span class="line">// 删除设备能力</span><br><span class="line">void removeCapabilities(oc_device_t *device);</span><br><span class="line"></span><br><span class="line">// 保存设备Profile</span><br><span class="line">void setProfiles(oc_device_t *device, struct _trt__GetProfilesResponse *profiles);</span><br><span class="line">// 删除设备Profile</span><br><span class="line">void removeProfiles(oc_device_t *device);</span><br><span class="line">    </span><br><span class="line">#ifdef __cplusplus</span><br><span class="line">&#125;</span><br><span class="line">#endif</span><br><span class="line">    </span><br><span class="line">#endif /* OnvifDevice_h */</span><br><span class="line"></span><br><span class="line">// 注意，设备相关操作需使用函数，不要直接操作结构体，否则会造成内存泄露</span><br></pre></td></tr></table></figure></p>
<p>OnvifDevice.c<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br></pre></td><td class="code"><pre><span class="line">#include &quot;OnvifDevice.h&quot;</span><br><span class="line"></span><br><span class="line">oc_device_t *createDevice(const char *xAddr, const char *userName, const char *password)</span><br><span class="line">&#123;</span><br><span class="line">    assert(NULL != xAddr);</span><br><span class="line">    assert(NULL != userName);</span><br><span class="line">    assert(NULL != password);</span><br><span class="line">    </span><br><span class="line">    oc_device_t *device = malloc(sizeof(oc_device_t));</span><br><span class="line">    memset(device, 0, sizeof(oc_device_t));</span><br><span class="line">    </span><br><span class="line">    device-&gt;xAddr = malloc(strlen(xAddr));</span><br><span class="line">    bzero(device-&gt;xAddr, strlen(xAddr)+1);</span><br><span class="line">    memcpy(device-&gt;xAddr, xAddr, strlen(xAddr));</span><br><span class="line">    </span><br><span class="line">    device-&gt;userName = malloc(strlen(userName));</span><br><span class="line">    bzero(device-&gt;userName, strlen(userName)+1);</span><br><span class="line">    memcpy(device-&gt;userName, userName, strlen(userName));</span><br><span class="line">    </span><br><span class="line">    device-&gt;password = malloc(strlen(password));</span><br><span class="line">    bzero(device-&gt;password, strlen(password)+1);</span><br><span class="line">    memcpy(device-&gt;password, password, strlen(password));</span><br><span class="line">    return device;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">void destroyDevice(oc_device_t *device)</span><br><span class="line">&#123;</span><br><span class="line">    if (device == NULL) &#123;</span><br><span class="line">        return;</span><br><span class="line">    &#125;</span><br><span class="line">    if (device-&gt;xAddr != NULL) &#123;</span><br><span class="line">        free(device-&gt;xAddr);</span><br><span class="line">        device-&gt;xAddr = NULL;</span><br><span class="line">    &#125;</span><br><span class="line">    if (device-&gt;userName != NULL) &#123;</span><br><span class="line">        free(device-&gt;userName);</span><br><span class="line">        device-&gt;userName = NULL;</span><br><span class="line">    &#125;</span><br><span class="line">    if (device-&gt;password != NULL) &#123;</span><br><span class="line">        free(device-&gt;password);</span><br><span class="line">        device-&gt;password = NULL;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    removeInfo(device);</span><br><span class="line">    removeProfiles(device);</span><br><span class="line">    removeCapabilities(device);</span><br><span class="line">    </span><br><span class="line">    free(device);</span><br><span class="line">    device = NULL;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">void setInfo(oc_device_t *device, struct _tds__GetDeviceInformationResponse  *info)</span><br><span class="line">&#123;</span><br><span class="line">    if (device == NULL || info == NULL) &#123;</span><br><span class="line">        return;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    removeInfo(device);</span><br><span class="line">    if (info-&gt;Manufacturer != NULL) &#123;</span><br><span class="line">        device-&gt;devinfo.Manufacturer = malloc(strlen(info-&gt;Manufacturer)+1);</span><br><span class="line">        bzero(device-&gt;devinfo.Manufacturer, strlen(info-&gt;Manufacturer)+1);</span><br><span class="line">        memcpy(device-&gt;devinfo.Manufacturer, info-&gt;Manufacturer, strlen(info-&gt;Manufacturer));</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line">    if (info-&gt;FirmwareVersion != NULL) &#123;</span><br><span class="line">        device-&gt;devinfo.FirmwareVersion = malloc(strlen(info-&gt;FirmwareVersion)+1);</span><br><span class="line">        bzero(device-&gt;devinfo.FirmwareVersion, strlen(info-&gt;FirmwareVersion)+1);</span><br><span class="line">        memcpy(device-&gt;devinfo.FirmwareVersion, info-&gt;FirmwareVersion, strlen(info-&gt;FirmwareVersion));</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line">    if (info-&gt;SerialNumber != NULL) &#123;</span><br><span class="line">        device-&gt;devinfo.SerialNumber = malloc(strlen(info-&gt;SerialNumber)+1);</span><br><span class="line">        bzero(device-&gt;devinfo.SerialNumber, strlen(info-&gt;SerialNumber)+1);</span><br><span class="line">        memcpy(device-&gt;devinfo.SerialNumber, info-&gt;SerialNumber, strlen(info-&gt;SerialNumber));</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line">    if (info-&gt;HardwareId != NULL) &#123;</span><br><span class="line">        device-&gt;devinfo.HardwareId = malloc(strlen(info-&gt;HardwareId)+1);</span><br><span class="line">        bzero(device-&gt;devinfo.HardwareId, strlen(info-&gt;HardwareId)+1);</span><br><span class="line">        memcpy(device-&gt;devinfo.HardwareId, info-&gt;HardwareId, strlen(info-&gt;HardwareId));</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line">    if (info-&gt;HardwareId != NULL) &#123;</span><br><span class="line">        device-&gt;devinfo.Model = malloc(strlen(info-&gt;Model)+1);</span><br><span class="line">        bzero(device-&gt;devinfo.Model, strlen(info-&gt;Model)+1);</span><br><span class="line">        memcpy(device-&gt;devinfo.Model, info-&gt;Model, strlen(info-&gt;Model));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">void removeInfo(oc_device_t *device)</span><br><span class="line">&#123;</span><br><span class="line">    if (device-&gt;devinfo.FirmwareVersion !=  NULL) &#123;</span><br><span class="line">        free(device-&gt;devinfo.FirmwareVersion);</span><br><span class="line">        device-&gt;devinfo.FirmwareVersion = NULL;</span><br><span class="line">    &#125;</span><br><span class="line">    if (device-&gt;devinfo.Manufacturer !=  NULL) &#123;</span><br><span class="line">        free(device-&gt;devinfo.Manufacturer);</span><br><span class="line">        device-&gt;devinfo.Manufacturer = NULL;</span><br><span class="line">    &#125;</span><br><span class="line">    if (device-&gt;devinfo.Model !=  NULL) &#123;</span><br><span class="line">        free(device-&gt;devinfo.Model);</span><br><span class="line">        device-&gt;devinfo.Model = NULL;</span><br><span class="line">    &#125;</span><br><span class="line">    if (device-&gt;devinfo.SerialNumber !=  NULL) &#123;</span><br><span class="line">        free(device-&gt;devinfo.SerialNumber);</span><br><span class="line">        device-&gt;devinfo.SerialNumber = NULL;</span><br><span class="line">    &#125;</span><br><span class="line">    if (device-&gt;devinfo.HardwareId !=  NULL) &#123;</span><br><span class="line">        free(device-&gt;devinfo.HardwareId);</span><br><span class="line">        device-&gt;devinfo.HardwareId = NULL;</span><br><span class="line">    &#125;</span><br><span class="line">    memset(&amp;device-&gt;devinfo, 0, sizeof(device-&gt;devinfo));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">void setCapabilities(oc_device_t *device, struct tt__Capabilities  *capa)</span><br><span class="line">&#123;</span><br><span class="line">    if (device == NULL || capa == NULL) &#123;</span><br><span class="line">        return;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    removeCapabilities(device);</span><br><span class="line">    </span><br><span class="line">    if (capa-&gt;Analytics-&gt;XAddr != NULL) &#123;</span><br><span class="line">        device-&gt;capabilities.Analytics = malloc(sizeof(struct tt__AnalyticsCapabilities));</span><br><span class="line">        device-&gt;capabilities.Analytics-&gt;XAddr = malloc(strlen(capa-&gt;Analytics-&gt;XAddr)+1);</span><br><span class="line">        bzero(device-&gt;capabilities.Analytics-&gt;XAddr, strlen(capa-&gt;Analytics-&gt;XAddr)+1);</span><br><span class="line">        memcpy(device-&gt;capabilities.Analytics-&gt;XAddr, capa-&gt;Analytics-&gt;XAddr, strlen(capa-&gt;Analytics-&gt;XAddr));</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    if (capa-&gt;Device-&gt;XAddr != NULL) &#123;</span><br><span class="line">        device-&gt;capabilities.Device = malloc(sizeof(struct tt__DeviceCapabilities));</span><br><span class="line">        device-&gt;capabilities.Device-&gt;XAddr = malloc(strlen(capa-&gt;Device-&gt;XAddr)+1);</span><br><span class="line">        bzero(device-&gt;capabilities.Device-&gt;XAddr, strlen(capa-&gt;Device-&gt;XAddr)+1);</span><br><span class="line">        memcpy(device-&gt;capabilities.Device-&gt;XAddr, capa-&gt;Device-&gt;XAddr, strlen(capa-&gt;Device-&gt;XAddr));</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    if (capa-&gt;Events-&gt;XAddr != NULL) &#123;</span><br><span class="line">        device-&gt;capabilities.Events = malloc(sizeof(struct tt__EventCapabilities));</span><br><span class="line">        device-&gt;capabilities.Events-&gt;XAddr = malloc(strlen(capa-&gt;Events-&gt;XAddr)+1);</span><br><span class="line">        bzero(device-&gt;capabilities.Events-&gt;XAddr, strlen(capa-&gt;Events-&gt;XAddr)+1);</span><br><span class="line">        memcpy(device-&gt;capabilities.Events-&gt;XAddr, capa-&gt;Events-&gt;XAddr, strlen(capa-&gt;Events-&gt;XAddr));</span><br><span class="line">    &#125;</span><br><span class="line">   </span><br><span class="line">    if (capa-&gt;Imaging-&gt;XAddr != NULL) &#123;</span><br><span class="line">        device-&gt;capabilities.Imaging = malloc(sizeof(struct tt__ImagingCapabilities));</span><br><span class="line">        device-&gt;capabilities.Imaging-&gt;XAddr = malloc(strlen(capa-&gt;Imaging-&gt;XAddr)+1);</span><br><span class="line">        bzero(device-&gt;capabilities.Imaging-&gt;XAddr, strlen(capa-&gt;Imaging-&gt;XAddr)+1);</span><br><span class="line">        memcpy(device-&gt;capabilities.Imaging-&gt;XAddr, capa-&gt;Imaging-&gt;XAddr, strlen(capa-&gt;Imaging-&gt;XAddr));</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    if (capa-&gt;Media-&gt;XAddr != NULL) &#123;</span><br><span class="line">        device-&gt;capabilities.Media = malloc(sizeof(struct tt__MediaCapabilities));</span><br><span class="line">        device-&gt;capabilities.Media-&gt;XAddr = malloc(strlen(capa-&gt;Media-&gt;XAddr)+1);</span><br><span class="line">        bzero(device-&gt;capabilities.Media-&gt;XAddr, strlen(capa-&gt;Media-&gt;XAddr)+1);</span><br><span class="line">        memcpy(device-&gt;capabilities.Media-&gt;XAddr, capa-&gt;Media-&gt;XAddr, strlen(capa-&gt;Media-&gt;XAddr));</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    if (capa-&gt;PTZ-&gt;XAddr != NULL) &#123;</span><br><span class="line">        device-&gt;capabilities.PTZ = malloc(sizeof(struct tt__PTZCapabilities));</span><br><span class="line">        device-&gt;capabilities.PTZ-&gt;XAddr = malloc(strlen(capa-&gt;PTZ-&gt;XAddr)+1);</span><br><span class="line">        bzero(device-&gt;capabilities.PTZ-&gt;XAddr, strlen(capa-&gt;PTZ-&gt;XAddr)+1);</span><br><span class="line">        memcpy(device-&gt;capabilities.PTZ-&gt;XAddr, capa-&gt;PTZ-&gt;XAddr, strlen(capa-&gt;PTZ-&gt;XAddr));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">void removeCapabilities(oc_device_t *device)</span><br><span class="line">&#123;</span><br><span class="line">    if (device-&gt;capabilities.Analytics != NULL) &#123;</span><br><span class="line">        if (device-&gt;capabilities.Analytics-&gt;XAddr != NULL) &#123;</span><br><span class="line">            free(device-&gt;capabilities.Analytics-&gt;XAddr);</span><br><span class="line">            device-&gt;capabilities.Analytics-&gt;XAddr = NULL;</span><br><span class="line">        &#125;</span><br><span class="line">        free(device-&gt;capabilities.Analytics);</span><br><span class="line">        device-&gt;capabilities.Analytics = NULL;</span><br><span class="line">    &#125;</span><br><span class="line">    if (device-&gt;capabilities.Device != NULL) &#123;</span><br><span class="line">        if (device-&gt;capabilities.Device-&gt;XAddr != NULL) &#123;</span><br><span class="line">            free(device-&gt;capabilities.Device-&gt;XAddr);</span><br><span class="line">            device-&gt;capabilities.Device-&gt;XAddr = NULL;</span><br><span class="line">        &#125;</span><br><span class="line">        free(device-&gt;capabilities.Device);</span><br><span class="line">        device-&gt;capabilities.Device = NULL;</span><br><span class="line">    &#125;</span><br><span class="line">    if (device-&gt;capabilities.Events != NULL) &#123;</span><br><span class="line">        if (device-&gt;capabilities.Events-&gt;XAddr != NULL) &#123;</span><br><span class="line">            free(device-&gt;capabilities.Events-&gt;XAddr);</span><br><span class="line">            device-&gt;capabilities.Events-&gt;XAddr = NULL;</span><br><span class="line">        &#125;</span><br><span class="line">        free(device-&gt;capabilities.Events);</span><br><span class="line">        device-&gt;capabilities.Events = NULL;</span><br><span class="line">    &#125;</span><br><span class="line">    if (device-&gt;capabilities.Imaging != NULL) &#123;</span><br><span class="line">        if (device-&gt;capabilities.Imaging-&gt;XAddr != NULL) &#123;</span><br><span class="line">            free(device-&gt;capabilities.Imaging-&gt;XAddr);</span><br><span class="line">            device-&gt;capabilities.Imaging-&gt;XAddr = NULL;</span><br><span class="line">        &#125;</span><br><span class="line">        free(device-&gt;capabilities.Imaging);</span><br><span class="line">        device-&gt;capabilities.Imaging = NULL;</span><br><span class="line">    &#125;</span><br><span class="line">    if (device-&gt;capabilities.Media != NULL) &#123;</span><br><span class="line">        if (device-&gt;capabilities.Media-&gt;XAddr != NULL) &#123;</span><br><span class="line">            free(device-&gt;capabilities.Media-&gt;XAddr);</span><br><span class="line">            device-&gt;capabilities.Media-&gt;XAddr = NULL;</span><br><span class="line">        &#125;</span><br><span class="line">        free(device-&gt;capabilities.Media);</span><br><span class="line">        device-&gt;capabilities.Media = NULL;</span><br><span class="line">    &#125;</span><br><span class="line">    if (device-&gt;capabilities.PTZ != NULL) &#123;</span><br><span class="line">        if (device-&gt;capabilities.PTZ-&gt;XAddr != NULL) &#123;</span><br><span class="line">            free(device-&gt;capabilities.PTZ-&gt;XAddr);</span><br><span class="line">            device-&gt;capabilities.PTZ-&gt;XAddr = NULL;</span><br><span class="line">        &#125;</span><br><span class="line">        free(device-&gt;capabilities.PTZ);</span><br><span class="line">        device-&gt;capabilities.PTZ = NULL;</span><br><span class="line">    &#125;</span><br><span class="line">    if (device-&gt;capabilities.Extension != NULL) &#123;</span><br><span class="line">        free(device-&gt;capabilities.Extension);</span><br><span class="line">        device-&gt;capabilities.Extension = NULL;</span><br><span class="line">    &#125;</span><br><span class="line">    memset(&amp;device-&gt;capabilities, 0, sizeof(device-&gt;capabilities));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">void setProfiles(oc_device_t *device, struct _trt__GetProfilesResponse *profiles)</span><br><span class="line">&#123;</span><br><span class="line">    if (device == NULL || profiles == NULL) &#123;</span><br><span class="line">        return;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    removeProfiles(device);</span><br><span class="line">    device-&gt;profiles.__sizeProfiles = profiles-&gt;__sizeProfiles;</span><br><span class="line">    int i = 0;</span><br><span class="line">    device-&gt;profiles.Profiles = malloc(sizeof(struct tt__Profile) * profiles-&gt;__sizeProfiles);</span><br><span class="line">    for (i = 0; i &lt; profiles-&gt;__sizeProfiles; i++) &#123;</span><br><span class="line">        struct tt__Profile *profile = &amp;(device-&gt;profiles.Profiles[i]);</span><br><span class="line">        memcpy(profile, &amp;(profiles-&gt;Profiles[i]), sizeof(struct tt__Profile));</span><br><span class="line">        </span><br><span class="line">        profile-&gt;Name = malloc(strlen(profiles-&gt;Profiles[i].Name) + 1);</span><br><span class="line">        bzero(profile-&gt;Name, strlen(profiles-&gt;Profiles[i].Name) + 1);</span><br><span class="line">        memcpy(profile-&gt;Name, profiles-&gt;Profiles[i].Name, strlen(profiles-&gt;Profiles[i].Name));</span><br><span class="line">        </span><br><span class="line">        profile-&gt;token = malloc(strlen(profiles-&gt;Profiles[i].token) + 1);</span><br><span class="line">        bzero(profile-&gt;token, strlen(profiles-&gt;Profiles[i].token) + 1);</span><br><span class="line">        memcpy(profile-&gt;token, profiles-&gt;Profiles[i].token, strlen(profiles-&gt;Profiles[i].token));</span><br><span class="line">        </span><br><span class="line">        if (profiles-&gt;Profiles[i].PTZConfiguration != NULL) &#123;</span><br><span class="line">            profile-&gt;PTZConfiguration = malloc(sizeof(struct tt__PTZConfiguration));</span><br><span class="line">            memcpy(profile-&gt;PTZConfiguration, profiles-&gt;Profiles[i].PTZConfiguration, sizeof(struct tt__PTZConfiguration));</span><br><span class="line">            profile-&gt;PTZConfiguration-&gt;Name = malloc(strlen(profiles-&gt;Profiles[i].PTZConfiguration-&gt;Name) + 1);</span><br><span class="line">            bzero(profile-&gt;PTZConfiguration-&gt;Name, strlen(profiles-&gt;Profiles[i].PTZConfiguration-&gt;Name) + 1);</span><br><span class="line">            memcpy(profile-&gt;PTZConfiguration-&gt;Name, profiles-&gt;Profiles[i].PTZConfiguration-&gt;Name, strlen(profiles-&gt;Profiles[i].PTZConfiguration-&gt;Name));</span><br><span class="line">            profile-&gt;PTZConfiguration-&gt;token = malloc(strlen(profiles-&gt;Profiles[i].PTZConfiguration-&gt;token) + 1);</span><br><span class="line">            bzero(profile-&gt;PTZConfiguration-&gt;token, strlen(profiles-&gt;Profiles[i].PTZConfiguration-&gt;token) + 1);</span><br><span class="line">            memcpy(profile-&gt;PTZConfiguration-&gt;token, profiles-&gt;Profiles[i].PTZConfiguration-&gt;token, strlen(profiles-&gt;Profiles[i].PTZConfiguration-&gt;token));</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">void removeProfiles(oc_device_t *device)</span><br><span class="line">&#123;</span><br><span class="line">    if (device == NULL || device-&gt;profiles.__sizeProfiles == 0) &#123;</span><br><span class="line">        return;</span><br><span class="line">    &#125;</span><br><span class="line">    int i = 0;</span><br><span class="line">    for (i = 0; i &lt; device-&gt;profiles.__sizeProfiles; i++) &#123;</span><br><span class="line">        struct tt__Profile profile = device-&gt;profiles.Profiles[i];</span><br><span class="line">        if (profile.Name != NULL) &#123;</span><br><span class="line">            free(profile.Name);</span><br><span class="line">        &#125;</span><br><span class="line">        if (profile.token != NULL) &#123;</span><br><span class="line">            free(profile.token);</span><br><span class="line">        &#125;</span><br><span class="line">        if (profile.PTZConfiguration != NULL) &#123;</span><br><span class="line">            if (profile.PTZConfiguration-&gt;Name != NULL) &#123;</span><br><span class="line">                free(profile.PTZConfiguration-&gt;Name);</span><br><span class="line">            &#125;</span><br><span class="line">            if (profile.PTZConfiguration-&gt;token != NULL) &#123;</span><br><span class="line">                free(profile.PTZConfiguration-&gt;token);</span><br><span class="line">            &#125;</span><br><span class="line">            free(profile.PTZConfiguration);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    free(device-&gt;profiles.Profiles);</span><br><span class="line">    device-&gt;profiles.Profiles = NULL;</span><br><span class="line">    device-&gt;profiles.__sizeProfiles = 0;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<h4 id="二、ONVIF控制，代码主要参照上面教程简单修改"><a href="#二、ONVIF控制，代码主要参照上面教程简单修改" class="headerlink" title="二、ONVIF控制，代码主要参照上面教程简单修改"></a>二、ONVIF控制，代码主要参照上面教程简单修改</h4><p>OnvifControl.h<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line">#ifndef OnvifControl_h</span><br><span class="line">#define OnvifControl_h</span><br><span class="line"></span><br><span class="line">#include &quot;OnvifDevice.h&quot;</span><br><span class="line"></span><br><span class="line">#ifdef __cplusplus</span><br><span class="line">extern &quot;C&quot;&#123;</span><br><span class="line">#endif</span><br><span class="line"></span><br><span class="line">/// 搜索设备</span><br><span class="line">/// @param userInfo 传入传出的指针</span><br><span class="line">void ONVIF_DetectDevice(void (*cb)(void *userinfo, struct wsdd__ProbeMatchesType *wsdd__ProbeMatches), void *userInfo);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">/// 获取设备信息</span><br><span class="line">int ONVIF_GetDeviceInformation(oc_device_t *device);</span><br><span class="line"></span><br><span class="line">/// 获取设备服务地址</span><br><span class="line">int ONVIF_GetCapabilities(oc_device_t *device);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">/// 获取设备profile</span><br><span class="line">/// @param device 设备结构体</span><br><span class="line">int ONVIF_GetProfile(oc_device_t *device);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">int ONVIF_GetStreamUri(oc_device_t *device, int profileIndex, char *ioUri, unsigned int sizeuri);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">int ONVIF_PTZGetStatus(oc_device_t *device, struct tt__Vector2D *ioPosition, enum xsd__boolean *moving);</span><br><span class="line"></span><br><span class="line">/// ptz 方向控制</span><br><span class="line">/// @param device 设备</span><br><span class="line">/// @param direction 方向，0 左 1右  2上  3下</span><br><span class="line">int ONVIF_PTZRelativeMove(oc_device_t *device, int direction);</span><br><span class="line"></span><br><span class="line">#ifdef __cplusplus</span><br><span class="line">&#125;</span><br><span class="line">#endif</span><br><span class="line">    </span><br><span class="line">#endif /* OnvifControl_h */</span><br></pre></td></tr></table></figure></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br></pre></td><td class="code"><pre><span class="line">#include &quot;OnvifControl.h&quot;</span><br><span class="line"></span><br><span class="line">#define SOAP_ASSERT     assert</span><br><span class="line">#define SOAP_DBGLOG     printf</span><br><span class="line">#define SOAP_DBGERR     printf</span><br><span class="line"></span><br><span class="line">#define SOAP_TO         &quot;urn:schemas-xmlsoap-org:ws:2005:04:discovery&quot;</span><br><span class="line">#define SOAP_ACTION     &quot;http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe&quot;</span><br><span class="line"></span><br><span class="line">#define SOAP_MCAST_ADDR &quot;soap.udp://239.255.255.250:3702&quot;                       // onvif规定的组播地址</span><br><span class="line"></span><br><span class="line">#define SOAP_ITEM       &quot;&quot;                                                      // 寻找的设备范围</span><br><span class="line">#define SOAP_TYPES      &quot;dn:NetworkVideoTransmitter&quot;                            // 寻找的设备类型</span><br><span class="line"></span><br><span class="line">#define SOAP_SOCK_TIMEOUT    (10)   // socket超时时间（单秒秒）</span><br><span class="line"></span><br><span class="line">#define SOAP_CHECK_ERROR(result, soap, str) \</span><br><span class="line">do &#123; \</span><br><span class="line">if (SOAP_OK != (result) || SOAP_OK != (soap)-&gt;error) &#123; \</span><br><span class="line">soap_perror((soap), (str)); \</span><br><span class="line">if (SOAP_OK == (result)) &#123; \</span><br><span class="line">(result) = (soap)-&gt;error; \</span><br><span class="line">&#125; \</span><br><span class="line">goto EXIT; \</span><br><span class="line">&#125; \</span><br><span class="line">&#125; while (0)</span><br><span class="line"></span><br><span class="line">void uriWithAuth(const char *orignalUri, const char *userName, const char *password, char *ioAuthURI)</span><br><span class="line">&#123;</span><br><span class="line">    char *i = strchr(orignalUri, &apos;:&apos;);</span><br><span class="line">    long length = i - orignalUri + 3;</span><br><span class="line">    memcpy(ioAuthURI, orignalUri, length);</span><br><span class="line">    sprintf(ioAuthURI+length, &quot;%s:%s@&quot;, userName, password);</span><br><span class="line">    strcat(ioAuthURI, orignalUri + length);</span><br><span class="line">    printf(&quot;%s %s\n&quot;, ioAuthURI, i);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">void soap_perror(struct soap *soap, const char *str)</span><br><span class="line">&#123;</span><br><span class="line">    if (NULL == str) &#123;</span><br><span class="line">        SOAP_DBGERR(&quot;[soap] error: %d, %s, %s\n&quot;, soap-&gt;error, *soap_faultcode(soap), *soap_faultstring(soap));</span><br><span class="line">    &#125; else &#123;</span><br><span class="line">        SOAP_DBGERR(&quot;[soap] %s error: %d, %s, %s\n&quot;, str, soap-&gt;error, *soap_faultcode(soap), *soap_faultstring(soap));</span><br><span class="line">    &#125;</span><br><span class="line">    return;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">void* ONVIF_soap_malloc(struct soap *soap, unsigned int n)</span><br><span class="line">&#123;</span><br><span class="line">    void *p = NULL;</span><br><span class="line">    </span><br><span class="line">    if (n &gt; 0) &#123;</span><br><span class="line">        p = soap_malloc(soap, n);</span><br><span class="line">        SOAP_ASSERT(NULL != p);</span><br><span class="line">        memset(p, 0x00 ,n);</span><br><span class="line">    &#125;</span><br><span class="line">    return p;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">struct soap *ONVIF_soap_new(int timeout)</span><br><span class="line">&#123;</span><br><span class="line">    struct soap *soap = NULL;                                                   // soap环境变量</span><br><span class="line">    </span><br><span class="line">    SOAP_ASSERT(NULL != (soap = soap_new()));</span><br><span class="line">    </span><br><span class="line">    soap_set_namespaces(soap, namespaces);                                      // 设置soap的namespaces</span><br><span class="line">    soap-&gt;recv_timeout    = timeout;                                            // 设置超时（超过指定时间没有数据就退出）</span><br><span class="line">    soap-&gt;send_timeout    = timeout;</span><br><span class="line">    soap-&gt;connect_timeout = timeout;</span><br><span class="line">    </span><br><span class="line">#if defined(__linux__) || defined(__linux)                                      // 参考https://www.genivia.com/dev.html#client-c的修改：</span><br><span class="line">    soap-&gt;socket_flags = MSG_NOSIGNAL;                                          // To prevent connection reset errors</span><br><span class="line">#endif</span><br><span class="line">    </span><br><span class="line">    soap_set_mode(soap, SOAP_C_UTFSTRING);                                      // 设置为UTF-8编码，否则叠加中文OSD会乱码</span><br><span class="line">    </span><br><span class="line">    return soap;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">void ONVIF_soap_delete(struct soap *soap)</span><br><span class="line">&#123;</span><br><span class="line">    soap_destroy(soap);                                                         // remove deserialized class instances (C++ only)</span><br><span class="line">    soap_end(soap);                                                             // Clean up deserialized data (except class instances) and temporary data</span><br><span class="line">    soap_done(soap);                                                            // Reset, close communications, and remove callbacks</span><br><span class="line">    soap_free(soap);                                                            // Reset and deallocate the context created with soap_new or soap_copy</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">void ONVIF_init_header(struct soap *soap)</span><br><span class="line">&#123;</span><br><span class="line">    struct SOAP_ENV__Header *header = NULL;</span><br><span class="line">    </span><br><span class="line">    SOAP_ASSERT(NULL != soap);</span><br><span class="line">    </span><br><span class="line">    header = (struct SOAP_ENV__Header *)ONVIF_soap_malloc(soap, sizeof(struct SOAP_ENV__Header));</span><br><span class="line">    soap_default_SOAP_ENV__Header(soap, header);</span><br><span class="line">    header-&gt;wsa__MessageID = (char*)soap_wsa_rand_uuid(soap);</span><br><span class="line">    header-&gt;wsa__To        = (char*)ONVIF_soap_malloc(soap, strlen(SOAP_TO) + 1);</span><br><span class="line">    header-&gt;wsa__Action    = (char*)ONVIF_soap_malloc(soap, strlen(SOAP_ACTION) + 1);</span><br><span class="line">    strcpy(header-&gt;wsa__To, SOAP_TO);</span><br><span class="line">    strcpy(header-&gt;wsa__Action, SOAP_ACTION);</span><br><span class="line">    soap-&gt;header = header;</span><br><span class="line">    </span><br><span class="line">    return;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">void ONVIF_init_ProbeType(struct soap *soap, struct wsdd__ProbeType *probe)</span><br><span class="line">&#123;</span><br><span class="line">    struct wsdd__ScopesType *scope = NULL;                                      // 用于描述查找哪类的Web服务</span><br><span class="line">    </span><br><span class="line">    SOAP_ASSERT(NULL != soap);</span><br><span class="line">    SOAP_ASSERT(NULL != probe);</span><br><span class="line">    </span><br><span class="line">    scope = (struct wsdd__ScopesType *)ONVIF_soap_malloc(soap, sizeof(struct wsdd__ScopesType));</span><br><span class="line">    soap_default_wsdd__ScopesType(soap, scope);                                 // 设置寻找设备的范围</span><br><span class="line">    scope-&gt;__item = (char*)ONVIF_soap_malloc(soap, strlen(SOAP_ITEM) + 1);</span><br><span class="line">    strcpy(scope-&gt;__item, SOAP_ITEM);</span><br><span class="line">    </span><br><span class="line">    memset(probe, 0x00, sizeof(struct wsdd__ProbeType));</span><br><span class="line">    soap_default_wsdd__ProbeType(soap, probe);</span><br><span class="line">    probe-&gt;Scopes = scope;</span><br><span class="line">    probe-&gt;Types  = (char*)ONVIF_soap_malloc(soap, strlen(SOAP_TYPES) + 1);     // 设置寻找设备的类型</span><br><span class="line">    strcpy(probe-&gt;Types, SOAP_TYPES);</span><br><span class="line">    </span><br><span class="line">    return;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">static int ONVIF_SetAuthInfo(struct soap *soap, const char *username, const char *password)</span><br><span class="line">&#123;</span><br><span class="line">    int result = 0;</span><br><span class="line">    </span><br><span class="line">    SOAP_ASSERT(NULL != username);</span><br><span class="line">    SOAP_ASSERT(NULL != password);</span><br><span class="line">    </span><br><span class="line">    result = soap_wsse_add_UsernameTokenDigest(soap, NULL, username, password);</span><br><span class="line">    SOAP_CHECK_ERROR(result, soap, &quot;add_UsernameTokenDigest&quot;);</span><br><span class="line">    </span><br><span class="line">EXIT:</span><br><span class="line">    </span><br><span class="line">    return result;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">void ONVIF_DetectDevice(void (*cb)(void *userinfo, struct wsdd__ProbeMatchesType *wsdd__ProbeMatches), void *userInfo)</span><br><span class="line">&#123;</span><br><span class="line">  </span><br><span class="line">    int result = 0;</span><br><span class="line">    unsigned int count = 0;                                                     // 搜索到的设备个数</span><br><span class="line">    struct soap *soap = NULL;                                                   // soap环境变量</span><br><span class="line">    struct wsdd__ProbeType      req;                                            // 用于发送Probe消息</span><br><span class="line">    struct __wsdd__ProbeMatches rep;                                            // 用于接收Probe应答</span><br><span class="line">//    struct wsdd__ProbeMatchType *probeMatch;</span><br><span class="line">    </span><br><span class="line">    SOAP_ASSERT(NULL != (soap = ONVIF_soap_new(5)));</span><br><span class="line">    </span><br><span class="line">    ONVIF_init_header(soap);                                                    // 设置消息头描述</span><br><span class="line">    ONVIF_init_ProbeType(soap, &amp;req);                                           // 设置寻找的设备的范围和类型</span><br><span class="line">    result = soap_send___wsdd__Probe(soap, SOAP_MCAST_ADDR, NULL, &amp;req);        // 向组播地址广播Probe消息</span><br><span class="line">    while (SOAP_OK == result)                                                   // 开始循环接收设备发送过来的消息</span><br><span class="line">    &#123;</span><br><span class="line">        memset(&amp;rep, 0x00, sizeof(rep));</span><br><span class="line">        result = soap_recv___wsdd__ProbeMatches(soap, &amp;rep);</span><br><span class="line">        if (SOAP_OK == result) &#123;</span><br><span class="line">            if (soap-&gt;error) &#123;</span><br><span class="line">                soap_perror(soap, &quot;ProbeMatches&quot;);</span><br><span class="line">                if (NULL != cb) &#123;</span><br><span class="line">                    cb(userInfo, NULL);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; else &#123;                                                            // 成功接收到设备的应答消息</span><br><span class="line">                if (cb) &#123;</span><br><span class="line">                    cb(userInfo, rep.wsdd__ProbeMatches);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; else if (soap-&gt;error) &#123;</span><br><span class="line">            if (NULL != cb) &#123;</span><br><span class="line">                cb(userInfo, NULL);</span><br><span class="line">            &#125;</span><br><span class="line">            break;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    SOAP_DBGLOG(&quot;\ndetect end! It has detected %d devices!\n&quot;, count);</span><br><span class="line">    </span><br><span class="line">    if (NULL != soap) &#123;</span><br><span class="line">        ONVIF_soap_delete(soap);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    return ;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">int ONVIF_GetDeviceInformation(oc_device_t *device)</span><br><span class="line">&#123;</span><br><span class="line">    int result = 0;</span><br><span class="line">    struct soap *soap = NULL;</span><br><span class="line">    struct _tds__GetDeviceInformation           devinfo_req;</span><br><span class="line">    struct _tds__GetDeviceInformationResponse   devinfo_resp;</span><br><span class="line">    </span><br><span class="line">    SOAP_ASSERT(NULL != device-&gt;xAddr);</span><br><span class="line">    SOAP_ASSERT(NULL != (soap = ONVIF_soap_new(SOAP_SOCK_TIMEOUT)));</span><br><span class="line">    </span><br><span class="line">    ONVIF_SetAuthInfo(soap, device-&gt;userName, device-&gt;password);</span><br><span class="line">    </span><br><span class="line">    memset(&amp;devinfo_req, 0x00, sizeof(devinfo_req));</span><br><span class="line">    memset(&amp;devinfo_resp, 0x00, sizeof(struct _tds__GetDeviceInformationResponse));</span><br><span class="line">    result = soap_call___tds__GetDeviceInformation(soap, device-&gt;xAddr, NULL, &amp;devinfo_req, &amp;devinfo_resp);</span><br><span class="line">    SOAP_CHECK_ERROR(result, soap, &quot;GetDeviceInformation&quot;);</span><br><span class="line">    </span><br><span class="line">    if (result == SOAP_OK) &#123;</span><br><span class="line">        setInfo(device, &amp;devinfo_resp);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">EXIT:</span><br><span class="line">    </span><br><span class="line">    if (NULL != soap) &#123;</span><br><span class="line">        ONVIF_soap_delete(soap);</span><br><span class="line">    &#125;</span><br><span class="line">    return result;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">int ONVIF_GetCapabilities(oc_device_t *device)</span><br><span class="line">&#123;</span><br><span class="line">    int result = 0;</span><br><span class="line">    struct soap *soap = NULL;</span><br><span class="line">    struct _tds__GetCapabilities            req;</span><br><span class="line">    struct _tds__GetCapabilitiesResponse    rep;</span><br><span class="line">    </span><br><span class="line">    SOAP_ASSERT(NULL != device-&gt;xAddr);</span><br><span class="line">    SOAP_ASSERT(NULL != (soap = ONVIF_soap_new(SOAP_SOCK_TIMEOUT)));</span><br><span class="line">    </span><br><span class="line">    ONVIF_SetAuthInfo(soap, device-&gt;userName, device-&gt;password);</span><br><span class="line">    </span><br><span class="line">    memset(&amp;req, 0x00, sizeof(req));</span><br><span class="line">    memset(&amp;rep, 0x00, sizeof(rep));</span><br><span class="line">    result = soap_call___tds__GetCapabilities(soap, device-&gt;xAddr, NULL, &amp;req, &amp;rep);</span><br><span class="line">    SOAP_CHECK_ERROR(result, soap, &quot;GetCapabilities&quot;);</span><br><span class="line">    </span><br><span class="line">    if (result == SOAP_OK) &#123;</span><br><span class="line">        setCapabilities(device, rep.Capabilities);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">EXIT:</span><br><span class="line">    if (NULL != soap) &#123;</span><br><span class="line">        ONVIF_soap_delete(soap);</span><br><span class="line">    &#125;</span><br><span class="line">    return result;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">int ONVIF_GetProfile(oc_device_t *device)</span><br><span class="line">&#123;</span><br><span class="line">    int result = 0;</span><br><span class="line">    struct soap *soap = NULL;</span><br><span class="line">    struct _trt__GetProfiles                req;</span><br><span class="line">    struct _trt__GetProfilesResponse        resp;</span><br><span class="line">    </span><br><span class="line">    SOAP_ASSERT(NULL != device-&gt;capabilities.Media-&gt;XAddr);</span><br><span class="line">    SOAP_ASSERT(NULL != (soap = ONVIF_soap_new(SOAP_SOCK_TIMEOUT)));</span><br><span class="line">    </span><br><span class="line">    ONVIF_SetAuthInfo(soap, device-&gt;userName, device-&gt;password);</span><br><span class="line">    </span><br><span class="line">    memset(&amp;req, 0x00, sizeof(req));</span><br><span class="line">    memset(&amp;resp, 0x00, sizeof(resp));</span><br><span class="line">    </span><br><span class="line">    result = SOAP_FMAC6 soap_call___trt__GetProfiles(soap, device-&gt;capabilities.Media-&gt;XAddr, NULL, &amp;req, &amp;resp);</span><br><span class="line">    SOAP_CHECK_ERROR(result, soap, &quot;GetProfile&quot;);</span><br><span class="line">    if (result == SOAP_OK) &#123;</span><br><span class="line">        setProfiles(device, &amp;resp);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">EXIT:</span><br><span class="line">    if (NULL != soap) &#123;</span><br><span class="line">        ONVIF_soap_delete(soap);</span><br><span class="line">    &#125;</span><br><span class="line">    return result;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">int ONVIF_GetStreamUri(oc_device_t *device, int profileIndex, char *ioUri, unsigned int sizeuri)</span><br><span class="line">&#123;</span><br><span class="line">    int result = 0;</span><br><span class="line">    struct soap *soap = NULL;</span><br><span class="line">    struct tt__StreamSetup              ttStreamSetup;</span><br><span class="line">    struct tt__Transport                ttTransport;</span><br><span class="line">    struct _trt__GetStreamUri           req;</span><br><span class="line">    struct _trt__GetStreamUriResponse   rep;</span><br><span class="line">    </span><br><span class="line">    SOAP_ASSERT(NULL != device-&gt;capabilities.Media-&gt;XAddr);</span><br><span class="line">    SOAP_ASSERT(profileIndex &lt; device-&gt;profiles.__sizeProfiles);</span><br><span class="line">    SOAP_ASSERT(NULL != device-&gt;profiles.Profiles[profileIndex].token);</span><br><span class="line">    SOAP_ASSERT(NULL != ioUri);</span><br><span class="line">    memset(ioUri, 0x00, sizeuri);</span><br><span class="line">    </span><br><span class="line">    SOAP_ASSERT(NULL != (soap = ONVIF_soap_new(SOAP_SOCK_TIMEOUT)));</span><br><span class="line">    </span><br><span class="line">    memset(&amp;req, 0x00, sizeof(req));</span><br><span class="line">    memset(&amp;rep, 0x00, sizeof(rep));</span><br><span class="line">    memset(&amp;ttStreamSetup, 0x00, sizeof(ttStreamSetup));</span><br><span class="line">    memset(&amp;ttTransport, 0x00, sizeof(ttTransport));</span><br><span class="line">    ttStreamSetup.Stream                = tt__StreamType__RTP_Unicast;</span><br><span class="line">    ttStreamSetup.Transport             = &amp;ttTransport;</span><br><span class="line">    ttStreamSetup.Transport-&gt;Protocol   = tt__TransportProtocol__RTSP;</span><br><span class="line">    ttStreamSetup.Transport-&gt;Tunnel     = NULL;</span><br><span class="line">    req.StreamSetup                     = &amp;ttStreamSetup;</span><br><span class="line">    req.ProfileToken                    = device-&gt;profiles.Profiles[profileIndex].token;</span><br><span class="line">    </span><br><span class="line">    ONVIF_SetAuthInfo(soap, device-&gt;userName, device-&gt;password);</span><br><span class="line">    result = soap_call___trt__GetStreamUri(soap, device-&gt;capabilities.Media-&gt;XAddr, NULL, &amp;req, &amp;rep);</span><br><span class="line">    SOAP_CHECK_ERROR(result, soap, &quot;GetServices&quot;);</span><br><span class="line">    </span><br><span class="line">    result = -1;</span><br><span class="line">    if (NULL != rep.MediaUri) &#123;</span><br><span class="line">        if (NULL != rep.MediaUri-&gt;Uri) &#123;</span><br><span class="line">            if (sizeuri &gt; strlen(rep.MediaUri-&gt;Uri)) &#123;</span><br><span class="line">                uriWithAuth(rep.MediaUri-&gt;Uri, device-&gt;userName, device-&gt;password, ioUri);</span><br><span class="line">                result = 0;</span><br><span class="line">            &#125; else &#123;</span><br><span class="line">                SOAP_DBGERR(&quot;Not enough cache!\n&quot;);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">EXIT:</span><br><span class="line">    </span><br><span class="line">    if (NULL != soap) &#123;</span><br><span class="line">        ONVIF_soap_delete(soap);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    return result;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">int ONVIF_PTZGetStatus(oc_device_t *device, struct tt__Vector2D *ioPosition, enum xsd__boolean *moving)</span><br><span class="line">&#123;</span><br><span class="line">    int result = 0;</span><br><span class="line">    struct soap *soap = NULL;</span><br><span class="line">    struct _tptz__GetStatus           req;</span><br><span class="line">    struct _tptz__GetStatusResponse   rep;</span><br><span class="line">    </span><br><span class="line">    SOAP_ASSERT(NULL != device-&gt;capabilities.PTZ-&gt;XAddr);</span><br><span class="line">    SOAP_ASSERT(NULL != device-&gt;profiles.Profiles[0].PTZConfiguration-&gt;token);</span><br><span class="line">    SOAP_ASSERT(NULL != (soap = ONVIF_soap_new(SOAP_SOCK_TIMEOUT)));</span><br><span class="line">    </span><br><span class="line">    memset(&amp;req, 0x00, sizeof(req));</span><br><span class="line">    memset(&amp;rep, 0x00, sizeof(rep));</span><br><span class="line">    req.ProfileToken = device-&gt;profiles.Profiles[0].PTZConfiguration-&gt;token;</span><br><span class="line">    </span><br><span class="line">    ONVIF_SetAuthInfo(soap, device-&gt;userName, device-&gt;password);</span><br><span class="line">    result = soap_call___tptz__GetStatus(soap, device-&gt;capabilities.PTZ-&gt;XAddr, NULL, &amp;req, &amp;rep);</span><br><span class="line">    SOAP_CHECK_ERROR(result, soap, &quot;GetVideoEncoderConfigurationOptions&quot;);</span><br><span class="line">    </span><br><span class="line">    if (result == SOAP_OK) &#123;</span><br><span class="line">        if (rep.PTZStatus != NULL &amp;&amp; rep.PTZStatus-&gt;Position != NULL ) &#123;</span><br><span class="line">            ioPosition-&gt;x = rep.PTZStatus-&gt;Position-&gt;PanTilt-&gt;x;</span><br><span class="line">            ioPosition-&gt;y = rep.PTZStatus-&gt;Position-&gt;PanTilt-&gt;y;</span><br><span class="line">        &#125;</span><br><span class="line">        if (rep.PTZStatus != NULL &amp;&amp; rep.PTZStatus-&gt;MoveStatus != NULL) &#123;</span><br><span class="line">            *moving = (rep.PTZStatus-&gt;MoveStatus-&gt;PanTilt || rep.PTZStatus-&gt;MoveStatus-&gt;Zoom);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">EXIT:</span><br><span class="line">    </span><br><span class="line">    if (NULL != soap) &#123;</span><br><span class="line">        ONVIF_soap_delete(soap);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    return result;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">int ONVIF_PTZRelativeMove(oc_device_t *device, int direction)</span><br><span class="line">&#123;</span><br><span class="line">    int result = 0;</span><br><span class="line">    struct soap *soap = NULL;</span><br><span class="line">    struct _tptz__AbsoluteMove           req;</span><br><span class="line">    struct _tptz__AbsoluteMoveResponse   rep;</span><br><span class="line">    </span><br><span class="line">    SOAP_ASSERT(NULL != device);</span><br><span class="line">    SOAP_ASSERT(NULL != device-&gt;capabilities.PTZ-&gt;XAddr);</span><br><span class="line">    SOAP_ASSERT(NULL != device-&gt;profiles.Profiles[0].PTZConfiguration-&gt;token);</span><br><span class="line">    SOAP_ASSERT(NULL != (soap = ONVIF_soap_new(SOAP_SOCK_TIMEOUT)));</span><br><span class="line">    </span><br><span class="line">    memset(&amp;req, 0x00, sizeof(req));</span><br><span class="line">    memset(&amp;rep, 0x00, sizeof(rep));</span><br><span class="line">    </span><br><span class="line">    struct tt__Vector2D position = &#123;0&#125;;</span><br><span class="line">    enum xsd__boolean moving = xsd__boolean__false_;</span><br><span class="line">    ONVIF_PTZGetStatus(device, &amp;position, &amp;moving);</span><br><span class="line">    if (moving) &#123;</span><br><span class="line">        return -1;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    printf(&quot;ptz position: x = %.1f, y = %.1f\n&quot;, position.x, position.y);</span><br><span class="line">    </span><br><span class="line">    struct tt__PTZVector Translation = &#123;0&#125;;</span><br><span class="line">    /** Optional element &apos;tptz:Speed&apos; of XML schema type &apos;tt:PTZSpeed&apos; */</span><br><span class="line">    struct tt__PTZSpeed Speed = &#123;0&#125;;</span><br><span class="line">    </span><br><span class="line">    req.ProfileToken = device-&gt;profiles.Profiles[0].PTZConfiguration-&gt;token;</span><br><span class="line">    struct tt__Vector2D PanTilt = &#123;0&#125;;</span><br><span class="line">    switch (direction) &#123;</span><br><span class="line">        case 0:</span><br><span class="line">            PanTilt.x = position.x + 0.1;</span><br><span class="line">            break;</span><br><span class="line">        case 1:</span><br><span class="line">            PanTilt.x = position.x - 0.1;</span><br><span class="line">            break;</span><br><span class="line">        case 2:</span><br><span class="line">            PanTilt.y = position.y + 0.1;</span><br><span class="line">            break;</span><br><span class="line">        case 3:</span><br><span class="line">            PanTilt.y = position.y - 0.1;</span><br><span class="line">            break;</span><br><span class="line">        default:</span><br><span class="line">            break;</span><br><span class="line">    &#125;</span><br><span class="line">    Translation.PanTilt = &amp;PanTilt;</span><br><span class="line">    req.Position= &amp;Translation;</span><br><span class="line">    </span><br><span class="line">    struct tt__Vector2D speed = &#123;0&#125;;</span><br><span class="line">    speed.x = 1;</span><br><span class="line">    speed.y = 1;</span><br><span class="line">    Speed.PanTilt = &amp;speed;</span><br><span class="line">    req.Speed = &amp;Speed;</span><br><span class="line">    </span><br><span class="line">    ONVIF_SetAuthInfo(soap, device-&gt;userName, device-&gt;password);</span><br><span class="line">    result = soap_call___tptz__AbsoluteMove(soap, device-&gt;capabilities.PTZ-&gt;XAddr, NULL, &amp;req, &amp;rep);</span><br><span class="line">    SOAP_CHECK_ERROR(result, soap, &quot;GetVideoEncoderConfigurationOptions&quot;);</span><br><span class="line">    </span><br><span class="line">EXIT:</span><br><span class="line">    </span><br><span class="line">    if (NULL != soap) &#123;</span><br><span class="line">        ONVIF_soap_delete(soap);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    return result;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ul>
<li>不知道是不是由于所使用的ipc是杂牌的原因，<strong>ONVIF_PTZGetStatus</strong> 无法获取到ipc当前ptz的准确偏移位置，所有实现准确的移动。</li>
</ul>


                
            </div>

            <!-- Comments -->
            
                <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                    


                </div>
            
        </div>
    </div>
</article>

    <!-- Footer -->
    <hr>

<!-- Footer -->
<footer>
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <ul class="list-inline text-center">
                    

                    

                    
                        <li>
                            <a href="https://github.com/klugjo/hexo-theme-clean-blog" target="_blank">
                                <span class="fa-stack fa-lg">
                                    <i class="fa fa-circle fa-stack-2x"></i>
                                    <i class="fa fa-github fa-stack-1x fa-inverse"></i>
                                </span>
                            </a>
                        </li>
                    

                    

                    

                    
                </ul>
                <p class="copyright text-muted">&copy; 2020 Cyrus<br></p>
                <p class="copyright text-muted">Original Theme <a target="_blank" href="http://startbootstrap.com/template-overviews/clean-blog/">Clean Blog</a> from <a href="http://startbootstrap.com/" target="_blank">Start Bootstrap</a></p>
                <p class="copyright text-muted">Adapted for <a target="_blank" href="https://hexo.io/">Hexo</a> by <a href="http://www.codeblocq.com/" target="_blank">Jonathan Klughertz</a></p>
                <p class="copyright text-muted"><a href="http://www.beian.miit.gov.cn">粤ICP备18110122号-1</a></p>
            </div>
        </div>
    </div>
</footer>


    <!-- After footer scripts -->
    
<!-- jQuery -->
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>

<!-- Bootstrap -->
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>

<!-- Gallery -->
<script src="//cdnjs.cloudflare.com/ajax/libs/featherlight/1.3.5/featherlight.min.js" type="text/javascript" charset="utf-8"></script>

<!-- Disqus Comments -->



</body>

</html>